import { h } from "vue";
import { VxeColumnPropTypes, VxeGlobalRendererHandles, FormItemRenderOptions, FormItemContentRenderParams } from "../../../../../types/all";
import XEUtils from "xe-utils";
import { createCellRender, isEmptyValue, createExportMethod, createProps, getItemOns, getCellEditFilterProps, getFilterOns, handleConfirmFilter, getEditOns, getComponent } from "./common";

function renderOptions(options: any[], optionProps: VxeGlobalRendererHandles.RenderOptionProps) {
    const labelProp = optionProps.label || "label";
    const valueProp = optionProps.value || "value";
    return XEUtils.map(options, (item, oIndex) => {
        return h(getComponent("ElOption"), {
            key: oIndex,
            value: item[valueProp],
            label: item[labelProp],
            disabled: item.disabled,
        });
    });
}

function createEditRender() {
    return function (renderOpts: VxeColumnPropTypes.EditRender, params: VxeGlobalRendererHandles.RenderEditParams) {
        const { options = [], optionGroups, optionProps = {}, optionGroupProps = {} } = renderOpts;
        const { row, column } = params;
        const { attrs } = renderOpts;
        const cellValue = XEUtils.get(row, column.field);
        const props = getCellEditFilterProps(renderOpts, params, cellValue);
        const ons = getEditOns(renderOpts, params);
        if (optionGroups) {
            const groupOptions = optionGroupProps.options || "options";
            const groupLabel = optionGroupProps.label || "label";
            return [
                h(
                    getComponent("ElSelect"),
                    {
                        ...attrs,
                        ...props,
                        ...ons,
                    },
                    {
                        default: () => {
                            return XEUtils.map(optionGroups, (group, gIndex) => {
                                return h(
                                    getComponent("ElOptionGroup"),
                                    {
                                        key: gIndex,
                                        label: group[groupLabel],
                                    },
                                    {
                                        default: () => renderOptions(group[groupOptions], optionProps),
                                    }
                                );
                            });
                        },
                    }
                ),
            ];
        }
        return [
            h(
                getComponent("ElSelect"),
                {
                    ...props,
                    ...attrs,
                    ...ons,
                },
                {
                    default: () => renderOptions(options, optionProps),
                }
            ),
        ];
    };
}

function getSelectCellValue(renderOpts: VxeGlobalRendererHandles.RenderCellOptions, params: VxeGlobalRendererHandles.RenderCellParams) {
    const { options = [], optionGroups, props = {}, optionProps = {}, optionGroupProps = {} } = renderOpts;
    const { row, column } = params;
    const labelProp = optionProps.label || "label";
    const valueProp = optionProps.value || "value";
    const groupOptions = optionGroupProps.options || "options";
    const cellValue = XEUtils.get(row, column.field as string);
    if (!isEmptyValue(cellValue)) {
        return XEUtils.map(
            props.mode === "multiple" ? cellValue : [cellValue],
            optionGroups
                ? (value) => {
                      let selectItem;
                      for (let index = 0; index < optionGroups.length; index++) {
                          selectItem = XEUtils.find(optionGroups[index][groupOptions], (item) => item[valueProp] === value);
                          if (selectItem) {
                              break;
                          }
                      }
                      return selectItem ? selectItem[labelProp] : value;
                  }
                : (value) => {
                      const selectItem = XEUtils.find(options, (item) => item[valueProp] === value);
                      return selectItem ? selectItem[labelProp] : value;
                  }
        ).join(", ");
    }
    return "";
}

function createFilterRender() {
    return function (renderOpts: VxeColumnPropTypes.FilterRender, params: VxeGlobalRendererHandles.RenderFilterParams) {
        const { options = [], optionGroups, optionProps = {}, optionGroupProps = {} } = renderOpts;
        const groupOptions = optionGroupProps.options || "options";
        const groupLabel = optionGroupProps.label || "label";
        const { column } = params;
        const { attrs } = renderOpts;
        return [
            h(
                "div",
                {
                    class: "vxe-table--filter-element-wrapper",
                },
                optionGroups
                    ? column.filters.map((option, oIndex) => {
                          const optionValue = option.data;
                          const props = getCellEditFilterProps(renderOpts, params, optionValue);
                          return h(
                              getComponent("ElSelect"),
                              {
                                  key: oIndex,
                                  ...attrs,
                                  ...props,
                                  ...getFilterOns(renderOpts, params, option, () => {
                                      // 处理 change 事件相关逻辑
                                      handleConfirmFilter(params, props.multiple ? option.data && option.data.length > 0 : !XEUtils.eqNull(option.data), option);
                                  }),
                              },
                              {
                                  default: () => {
                                      return XEUtils.map(optionGroups, (group, gIndex) => {
                                          return h(
                                              getComponent("ElOptionGroup"),
                                              {
                                                  key: gIndex,
                                                  label: group[groupLabel],
                                              },
                                              {
                                                  default: () => renderOptions(group[groupOptions], optionProps),
                                              }
                                          );
                                      });
                                  },
                              }
                          );
                      })
                    : column.filters.map((option, oIndex) => {
                          const optionValue = option.data;
                          const props = getCellEditFilterProps(renderOpts, params, optionValue);
                          return h(
                              getComponent("ElSelect"),
                              {
                                  key: oIndex,
                                  ...attrs,
                                  ...props,
                                  ...getFilterOns(renderOpts, params, option, () => {
                                      // 处理 change 事件相关逻辑
                                      handleConfirmFilter(params, props.multiple ? option.data && option.data.length > 0 : !XEUtils.eqNull(option.data), option);
                                  }),
                              },
                              {
                                  default: () => renderOptions(options, optionProps),
                              }
                          );
                      })
            ),
        ];
    };
}

function createFormItemRender(defaultProps?: { [key: string]: any }, callBack?: (renderOpts: FormItemRenderOptions, params: FormItemContentRenderParams) => Record<string, any>) {
    return function (renderOpts: FormItemRenderOptions, params: FormItemContentRenderParams) {
        const args = (callBack && callBack(renderOpts, params)) ?? {};
        const { options = [], optionGroups, optionProps = {}, optionGroupProps = {} } = renderOpts;
        const { data, field }: any = params;
        const { attrs } = renderOpts;
        const itemValue = XEUtils.get(data, field);
        const props = createProps(renderOpts, itemValue, params);
        const ons = getItemOns(renderOpts, params);
        if (optionGroups) {
            const groupOptions = optionGroupProps.options || "options";
            const groupLabel = optionGroupProps.label || "label";
            return [
                h(
                    getComponent("ElSelect"),
                    {
                        ...attrs,
                        ...props,
                        ...ons,
                        ...args,
                    },
                    {
                        default: () => {
                            return XEUtils.map(optionGroups, (group, gIndex) => {
                                return h(
                                    getComponent("ElOptionGroup"),
                                    {
                                        label: group[groupLabel],
                                        key: gIndex,
                                    },
                                    {
                                        default: () => renderOptions(group[groupOptions], optionProps),
                                    }
                                );
                            });
                        },
                    }
                ),
            ];
        }
        return [
            h(
                getComponent("ElSelect"),
                {
                    ...attrs,
                    ...props,
                    ...ons,
                },
                {
                    default: () => renderOptions(options, optionProps),
                }
            ),
        ];
    };
}

export default {
    renderEdit: createEditRender(),
    renderCell: createCellRender(getSelectCellValue),
    renderFilter: createFilterRender(),
    defaultFilterMethod(params: any) {
        const { option, row, column } = params;
        const { data } = option;
        const { field, filterRender: renderOpts } = column;
        const { props = {} } = renderOpts;
        const cellValue = XEUtils.get(row, field);
        if (props.mode === "multiple") {
            if (XEUtils.isArray(cellValue)) {
                return XEUtils.includeArrays(cellValue, data);
            }
            return data.indexOf(cellValue) > -1;
        }
        return cellValue == data;
    },
    renderItemContent: createFormItemRender(),
    exportMethod: createExportMethod(getSelectCellValue),
};
